﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing.Design;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Windows.Forms.VisualStyles;

namespace AdvancedDataGridView
{
    //[Docking(DockingBehavior.Ask)]
    //[Designer(typeof(System.Windows.Forms.Design.ControlDesigner))]
    //[ComplexBindingProperties]
    //[DesignerCategory("code")]
	public class TreeGridView : DataGridView
	{
		public TreeGridView()
		{
			base.EditMode = DataGridViewEditMode.EditProgrammatically;
			this.RowTemplate = new TreeGridNode();
			base.AllowUserToAddRows = false;
			base.AllowUserToDeleteRows = false;
			this._root = new TreeGridNode(this);
			this._root.IsRoot = true;
			base.Rows.CollectionChanged += delegate(object sender, CollectionChangeEventArgs e)
			{
			};
		}

		protected override void OnKeyDown(KeyEventArgs e)
		{
			base.OnKeyDown(e);
			if (!e.Handled)
			{
				if (e.KeyCode == Keys.F2 && base.CurrentCellAddress.X > -1 && base.CurrentCellAddress.Y > -1)
				{
					if (!base.CurrentCell.Displayed)
					{
						base.FirstDisplayedScrollingRowIndex = base.CurrentCellAddress.Y;
					}
					base.SelectionMode = DataGridViewSelectionMode.CellSelect;
					this.BeginEdit(true);
				}
				else if (e.KeyCode == Keys.Return && !base.IsCurrentCellInEditMode)
				{
					base.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
					base.CurrentCell.OwningRow.Selected = true;
				}
			}
		}

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public new object DataSource
		{
			get
			{
				return null;
			}
			set
			{
				throw new NotSupportedException("The TreeGridView does not support databinding");
			}
		}

		[Browsable(false)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new object DataMember
		{
			get
			{
				return null;
			}
			set
			{
				throw new NotSupportedException("The TreeGridView does not support databinding");
			}
		}

		[Browsable(false)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new DataGridViewRowCollection Rows
		{
			get
			{
				return base.Rows;
			}
		}

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public new bool VirtualMode
		{
			get
			{
				return false;
			}
			set
			{
				throw new NotSupportedException("The TreeGridView does not support virtual mode");
			}
		}

		[Browsable(false)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public new DataGridViewRow RowTemplate
		{
			get
			{
				return base.RowTemplate;
			}
			set
			{
				base.RowTemplate = value;
			}
		}

		[Description("Returns the TreeGridNode for the given DataGridViewRow")]
		public TreeGridNode GetNodeForRow(DataGridViewRow row)
		{
			return row as TreeGridNode;
		}

		[Description("Returns the TreeGridNode for the given DataGridViewRow")]
		public TreeGridNode GetNodeForRow(int index)
		{
			return this.GetNodeForRow(base.Rows[index]);
		}

        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        //[Description("The collection of root nodes in the treelist.")]
        //[Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
        //[Category("Data")]
		public TreeGridNodeCollection Nodes
		{
			get
			{
				return this._root.Nodes;
			}
		}

		public new TreeGridNode CurrentRow
		{
			get
			{
				return base.CurrentRow as TreeGridNode;
			}
		}

		[Description("Causes nodes to always show as expandable. Use the NodeExpanding event to add nodes.")]
		[DefaultValue(false)]
		public bool VirtualNodes
		{
			get
			{
				return this._virtualNodes;
			}
			set
			{
				this._virtualNodes = value;
			}
		}

		public TreeGridNode CurrentNode
		{
			get
			{
				return this.CurrentRow;
			}
		}

		[DefaultValue(true)]
		public bool ShowLines
		{
			get
			{
				return this._showLines;
			}
			set
			{
				if (value != this._showLines)
				{
					this._showLines = value;
					base.Invalidate();
				}
			}
		}

		public ImageList ImageList
		{
			get
			{
				return this._imageList;
			}
			set
			{
				this._imageList = value;
			}
		}

		public new int RowCount
		{
			get
			{
				return this.Nodes.Count;
			}
			set
			{
				for (int i = 0; i < value; i++)
				{
					this.Nodes.Add(new TreeGridNode());
				}
			}
		}

		protected override void OnRowsAdded(DataGridViewRowsAddedEventArgs e)
		{
			base.OnRowsAdded(e);
			for (int i = e.RowCount - 1; i >= 0; i--)
			{
				TreeGridNode treeGridNode = base.Rows[e.RowIndex + i] as TreeGridNode;
				if (treeGridNode != null)
				{
					treeGridNode.Sited();
				}
			}
		}

		protected internal void UnSiteAll()
		{
			this.UnSiteNode(this._root);
		}

		protected internal virtual void UnSiteNode(TreeGridNode node)
		{
			if (node.IsSited || node.IsRoot)
			{
				foreach (TreeGridNode node2 in node.Nodes)
				{
					this.UnSiteNode(node2);
				}
				if (!node.IsRoot)
				{
					base.Rows.Remove(node);
					node.UnSited();
				}
			}
		}

		protected internal virtual bool CollapseNode(TreeGridNode node)
		{
			bool result;
			if (node.IsExpanded)
			{
				CollapsingEventArgs collapsingEventArgs = new CollapsingEventArgs(node);
				this.OnNodeCollapsing(collapsingEventArgs);
				if (!collapsingEventArgs.Cancel)
				{
					this.LockVerticalScrollBarUpdate(true);
					base.SuspendLayout();
					this._inExpandCollapse = true;
					node.IsExpanded = false;
					foreach (TreeGridNode treeGridNode in node.Nodes)
					{
						Debug.Assert(treeGridNode.RowIndex != -1, "Row is NOT in the grid.");
						this.UnSiteNode(treeGridNode);
					}
					CollapsedEventArgs e = new CollapsedEventArgs(node);
					this.OnNodeCollapsed(e);
					this._inExpandCollapse = false;
					this.LockVerticalScrollBarUpdate(false);
					base.ResumeLayout(true);
					base.InvalidateCell(node.Cells[0]);
				}
				result = !collapsingEventArgs.Cancel;
			}
			else
			{
				result = false;
			}
			return result;
		}

		protected internal virtual void SiteNode(TreeGridNode node)
		{
			node._grid = this;
			TreeGridNode treeGridNode;
			if (node.Parent != null && !node.Parent.IsRoot)
			{
				Debug.Assert(node.Parent != null && node.Parent.IsExpanded);
				if (node.Index > 0)
				{
					treeGridNode = node.Parent.Nodes[node.Index - 1];
				}
				else
				{
					treeGridNode = node.Parent;
				}
			}
			else if (node.Index > 0)
			{
				treeGridNode = node.Parent.Nodes[node.Index - 1];
			}
			else
			{
				treeGridNode = null;
			}
			int num;
			if (treeGridNode != null)
			{
				while (treeGridNode.Level >= node.Level)
				{
					if (treeGridNode.RowIndex >= base.Rows.Count - 1)
					{
						break;
					}
					treeGridNode = (base.Rows[treeGridNode.RowIndex + 1] as TreeGridNode);
					Debug.Assert(treeGridNode != null);
				}
				if (treeGridNode == node.Parent)
				{
					num = treeGridNode.RowIndex + 1;
				}
				else if (treeGridNode.Level < node.Level)
				{
					num = treeGridNode.RowIndex;
				}
				else
				{
					num = treeGridNode.RowIndex + 1;
				}
			}
			else
			{
				num = 0;
			}
			Debug.Assert(num != -1);
			this.SiteNode(node, num);
			Debug.Assert(node.IsSited);
			if (node.IsExpanded)
			{
				foreach (TreeGridNode node2 in node.Nodes)
				{
					this.SiteNode(node2);
				}
			}
		}

		protected internal virtual void SiteNode(TreeGridNode node, int index)
		{
			if (index < base.Rows.Count)
			{
				base.Rows.Insert(index, node);
			}
			else
			{
				base.Rows.Add(node);
			}
		}

		protected internal virtual bool ExpandNode(TreeGridNode node)
		{
			bool result;
			if (!node.IsExpanded || this._virtualNodes)
			{
				ExpandingEventArgs expandingEventArgs = new ExpandingEventArgs(node);
				this.OnNodeExpanding(expandingEventArgs);
				if (!expandingEventArgs.Cancel)
				{
					this.LockVerticalScrollBarUpdate(true);
					base.SuspendLayout();
					this._inExpandCollapse = true;
					node.IsExpanded = true;
					foreach (TreeGridNode treeGridNode in node.Nodes)
					{
						Debug.Assert(treeGridNode.RowIndex == -1, "Row is already in the grid.");
						this.SiteNode(treeGridNode);
					}
					ExpandedEventArgs e = new ExpandedEventArgs(node);
					this.OnNodeExpanded(e);
					this._inExpandCollapse = false;
					this.LockVerticalScrollBarUpdate(false);
					base.ResumeLayout(true);
					base.InvalidateCell(node.Cells[0]);
				}
				result = !expandingEventArgs.Cancel;
			}
			else
			{
				result = false;
			}
			return result;
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			base.OnMouseUp(e);
			this._inExpandCollapseMouseCapture = false;
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			if (!this._inExpandCollapseMouseCapture)
			{
				base.OnMouseMove(e);
			}
		}

		public event ExpandingEventHandler NodeExpanding;

		public event ExpandedEventHandler NodeExpanded;

		public event CollapsingEventHandler NodeCollapsing;

		public event CollapsedEventHandler NodeCollapsed;

		protected virtual void OnNodeExpanding(ExpandingEventArgs e)
		{
			if (this.NodeExpanding != null)
			{
				this.NodeExpanding(this, e);
			}
		}

		protected virtual void OnNodeExpanded(ExpandedEventArgs e)
		{
			if (this.NodeExpanded != null)
			{
				this.NodeExpanded(this, e);
			}
		}

		protected virtual void OnNodeCollapsing(CollapsingEventArgs e)
		{
			if (this.NodeCollapsing != null)
			{
				this.NodeCollapsing(this, e);
			}
		}

		protected virtual void OnNodeCollapsed(CollapsedEventArgs e)
		{
			if (this.NodeCollapsed != null)
			{
				this.NodeCollapsed(this, e);
			}
		}

		protected override void Dispose(bool disposing)
		{
			this._disposing = true;
			base.Dispose(base.Disposing);
			this.UnSiteAll();
		}

		protected override void OnHandleCreated(EventArgs e)
		{
			base.OnHandleCreated(e);
			this.hideScrollBarControl = new System.Windows.Forms.Control();
			this.hideScrollBarControl.Visible = false;
			this.hideScrollBarControl.Enabled = false;
			this.hideScrollBarControl.TabStop = false;
			base.Controls.Add(this.hideScrollBarControl);
		}

		protected override void OnRowEnter(DataGridViewCellEventArgs e)
		{
			base.OnRowEnter(e);
			if (base.SelectionMode == DataGridViewSelectionMode.CellSelect || (base.SelectionMode == DataGridViewSelectionMode.FullRowSelect && !base.Rows[e.RowIndex].Selected))
			{
				base.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
				base.Rows[e.RowIndex].Selected = true;
			}
		}

		private void LockVerticalScrollBarUpdate(bool lockUpdate)
		{
			if (!this._inExpandCollapse)
			{
				if (lockUpdate)
				{
					base.VerticalScrollBar.Parent = this.hideScrollBarControl;
				}
				else
				{
					base.VerticalScrollBar.Parent = this;
				}
			}
		}

		protected override void OnColumnAdded(DataGridViewColumnEventArgs e)
		{
			if (typeof(TreeGridColumn).IsAssignableFrom(e.Column.GetType()))
			{
				if (this._expandableColumn == null)
				{
					this._expandableColumn = (TreeGridColumn)e.Column;
				}
			}
			e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
			base.OnColumnAdded(e);
		}

		private int _indentWidth;

		private TreeGridNode _root;

		private TreeGridColumn _expandableColumn;

		private bool _disposing = false;

		internal ImageList _imageList;

		private bool _inExpandCollapse = false;

		internal bool _inExpandCollapseMouseCapture = false;

		private System.Windows.Forms.Control hideScrollBarControl;

		private bool _showLines = true;

		private bool _virtualNodes = false;

		internal VisualStyleRenderer rOpen = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);

		internal VisualStyleRenderer rClosed = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);

		[CompilerGenerated]
		private static CollectionChangeEventHandler ss9__CachedAnonymousMethodDelegate1 = null;

		private static class Win32Helper
		{
			[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
			public static extern IntPtr SendMessage(HandleRef hWnd, int msg, IntPtr wParam, IntPtr lParam);

			[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
			public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int lParam);

			[DllImport("USER32.DLL", CharSet = CharSet.Auto)]
			public static extern bool PostMessage(HandleRef hwnd, int msg, IntPtr wparam, IntPtr lparam);

			public const int WM_SYSKEYDOWN = 260;

			public const int WM_KEYDOWN = 256;

			public const int WM_SETREDRAW = 11;
		}
	}
}
